package com.tzy.rpc.transport.socket.server;/**
 * @description:
 * @Author HP
 * @create 2022/3/14 16:33
 */

import com.tzy.rpc.factory.ThreadPoolFactory;
import com.tzy.rpc.handler.RequestHandler;
import com.tzy.rpc.hook.ShutdownHook;
import com.tzy.rpc.provider.ServiceProviderImpl;
import com.tzy.rpc.register.NacosServiceRegistry;
import com.tzy.rpc.serializer.CommonSerializer;
import com.tzy.rpc.transport.AbstractRpcServer;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;

/**
 * @author HP
 * @create 2022-03-14 16:33
 * @desc rpc的server端socket实现
 **/
public class SoketServer extends AbstractRpcServer {

    private final ExecutorService threadPool;
    private RequestHandler requestHandler = new RequestHandler();
    private CommonSerializer serializer;

    //创建线程池，传入一个已经注册好服务的ServiceRegistry
    public SoketServer(String host,int port) {
        this.host=host;
        this.port=port;
        this.serviceRegistry = new NacosServiceRegistry();
        this.serviceProvider=new ServiceProviderImpl();
        threadPool = ThreadPoolFactory.createDefaultThreadPool("socket-rpc-server");
        scanServices();
    }

    //启动服务端
    @Override
    public void start() {
        try (ServerSocket serverSocket = new ServerSocket()) {
            serverSocket.bind(new InetSocketAddress(host, port));
            logger.info("服务器启动……");
            //添加钩子
            ShutdownHook.getShutdownHook().addClearAllHook();
            Socket socket;
            while((socket = serverSocket.accept()) != null) {
                logger.info("消费者连接: {}:{}", socket.getInetAddress(), socket.getPort());
                threadPool.execute(new SocketRequestHandlerThread(socket, requestHandler,serializer));
            }
            threadPool.shutdown();
        } catch (IOException e) {
            logger.error("服务器启动时有错误发生:", e);
        }
    }

    @Override
    public void setSerializer(CommonSerializer serializer) {
        this.serializer=serializer;
    }

}
